using AutoMapper;
using MediatR;
using RBAC.Domain.SmartHealthcare.Hosiptial;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using SmartHealthcare.Read.Api.Application.Command.HospitalExpense;
using SmartHealthcare.Read.Api.DTo;
using SmartHealthcare.Read.Api.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SmartHealthcare.Read.Api.Application.Handler.HospitalExpense
{
    /// <summary>
    /// 生成每日费用清单处理器
    /// </summary>
    public class GenerateDailyExpenseReportHandler : IRequestHandler<GenerateDailyExpenseReportCommand, APIResult<byte[]>>
    {
        private readonly IBaseRepository<HospitalExpenseModel> expenseRepository;
        private readonly IBaseRepository<PatientListModel> patientRepository;
        private readonly IBaseRepository<InpatientRegistryModel> registryRepository;

        private readonly IMapper mapper;
        private readonly ILogger<GenerateDailyExpenseReportHandler> logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="expenseRepository">住院费用记录仓储</param>
        /// <param name="patientRepository">患者信息仓储</param>
        /// <param name="registryRepository">住院登记仓储</param>
        /// <param name="pdfExportService">PDF导出服务</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GenerateDailyExpenseReportHandler(
            IBaseRepository<HospitalExpenseModel> expenseRepository,
            IBaseRepository<PatientListModel> patientRepository,
            IBaseRepository<InpatientRegistryModel> registryRepository,
            IMapper mapper,
            ILogger<GenerateDailyExpenseReportHandler> logger)
        {
            this.expenseRepository = expenseRepository;
            this.patientRepository = patientRepository;
            this.registryRepository = registryRepository;
           
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 处理生成每日费用清单请求
        /// </summary>
        /// <param name="request">请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>报表文件字节数组</returns>
        public Task<APIResult<byte[]>> Handle(GenerateDailyExpenseReportCommand request, CancellationToken cancellationToken)
        {
            APIResult<byte[]> result = new APIResult<byte[]>();

            try
            {
                // 设置报表日期，默认为当天
                var reportDate = request.ReportDate ?? DateTime.Now.Date;
                
                logger.LogInformation($"开始生成每日费用清单，病人卡号：{request.MedicalCard}，住院登记ID：{request.InpatientRegistryId}，报表日期：{reportDate:yyyy-MM-dd}");

                // 参数验证
                if (string.IsNullOrWhiteSpace(request.MedicalCard) && !request.InpatientRegistryId.HasValue)
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "病人卡号和住院登记ID不能同时为空";
                    return Task.FromResult(result);
                }

                // 构建查询条件
                var query = expenseRepository.GetALL().Where(e => e.IsDeleted == false);

                if (!string.IsNullOrWhiteSpace(request.MedicalCard))
                {
                    query = query.Where(e => e.MedicalCard == request.MedicalCard);
                }

                if (request.InpatientRegistryId.HasValue)
                {
                    query = query.Where(e => e.InpatientRegistryId == request.InpatientRegistryId.Value);
                }

                // 查询指定日期的费用记录
                var startDate = reportDate.Date;
                var endDate = startDate.AddDays(1);
                query = query.Where(e => e.ExpenseTime >= startDate && e.ExpenseTime < endDate);

                // 获取费用记录
                var expenses = query.OrderBy(e => e.ExpenseTime).ToList();

                if (expenses.Count == 0)
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = $"未找到 {reportDate:yyyy-MM-dd} 的费用记录";
                    return Task.FromResult(result);
                }

                // 获取患者信息
                var patientInfo = patientRepository.GetALL()
                    .Where(p => p.IsDeleted == false && p.MedicalCard == expenses.First().MedicalCard)
                    .FirstOrDefault();

                if (patientInfo == null)
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "未找到患者信息";
                    return Task.FromResult(result);
                }

                // 获取住院登记信息
                var inpatientRegistry = registryRepository.GetALL()
                    .Where(r => r.IsDeleted == false && r.Id == expenses.First().InpatientRegistryId)
                    .FirstOrDefault();

                // 创建报表数据模型
                var reportData = new DailyExpenseReportDto
                {
                    ReportDate = reportDate,
                    PatientName = patientInfo.PatientName,
                    MedicalCard = patientInfo.MedicalCard,
                    Gender = patientInfo.Gender,
                    Age = patientInfo.Age,
                    DepartmentName = expenses.First().DepartmentName,
                    BedNumber = inpatientRegistry?.WardId.ToString() ?? "未知",
                    AdmissionDate = inpatientRegistry?.AdmissionTime ?? DateTime.MinValue,
                    TotalAmount = expenses.Sum(e => e.TotalAmount),
                    InsuranceAmount = expenses.Sum(e => e.InsuranceAmount),
                    SelfPayAmount = expenses.Sum(e => e.SelfPayAmount),
                    ExpenseItems = expenses.Select(e => new ExpenseItemDto
                    {
                        ItemName = e.ItemName,
                        ItemType = e.ItemType,
                        Specification = e.Specification,
                        UnitPrice = e.UnitPrice,
                        Quantity = e.Quantity,
                        TotalAmount = e.TotalAmount,
                        InsuranceAmount = e.InsuranceAmount,
                        SelfPayAmount = e.SelfPayAmount,
                        ExpenseTime = e.ExpenseTime
                    }).ToList()
                };

                // 按类型统计
                reportData.TypeStatistics = expenses
                    .GroupBy(e => e.ItemType)
                    .Select(g => new ExpenseTypeStatisticsDto
                    {
                        ItemType = g.Key,
                        TotalAmount = g.Sum(e => e.TotalAmount),
                        InsuranceAmount = g.Sum(e => e.InsuranceAmount),
                        SelfPayAmount = g.Sum(e => e.SelfPayAmount),
                        ItemCount = g.Count()
                    })
                    .OrderByDescending(g => g.TotalAmount)
                    .ToList();

                // 生成报表
                byte[] reportBytes;
                
                if (request.ReportFormat.ToUpper() == "EXCEL")
                {
                    // 生成Excel报表
                    // TODO: 实现Excel导出功能
                    result.Code = APIEnums.Fail;
                    result.Msg = "Excel导出功能尚未实现";
                    return Task.FromResult(result);
                }
                else
                {
                    // 生成PDF报表
                    //reportBytes = pdfExportService.GenerateDailyExpenseReport(reportData);
                }

                result.Code = APIEnums.Success;
                result.Msg = "生成每日费用清单成功";
                //result.Data = reportBytes;

                logger.LogInformation($"生成每日费用清单成功，病人：{reportData.PatientName}，日期：{reportDate:yyyy-MM-dd}，总金额：{reportData.TotalAmount}");
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "生成每日费用清单时发生异常");
                result.Code = APIEnums.Error;
                result.Msg = "生成每日费用清单时发生异常：" + ex.Message;
            }

            return Task.FromResult(result);
        }
    }
} 